Skip to content

system: provide missing image type information - #41

Open
efahl wants to merge 1 commit into
openwrt:mainfrom
efahl:image-type
Open

system: provide missing image type information#41
efahl wants to merge 1 commit into
openwrt:mainfrom
efahl:image-type

Conversation

@efahl

@efahl efahl commented Aug 25, 2026

Copy link
Copy Markdown

An ongoing chronic pain point when performing upgrades is determining which of several images is the correct one. For most devices, this is a simple choice between "factory" or "sysupgrade", with the latter being the correct choice. On several targets, the choice is not so obvious.

For example, on the x86/64 target, we have "combined" and "combined-efi" images, and users must somehow determine which is appropriate. The armsr and loongarch devices are simpler with only "combined-efi", and tegra only has "sdcard". On the ramips/mt7621 target there are five Mikrotik devices that have both "sysupgrade" and "sysupgrade-v7". Further, the new spacemit/k1 target has three: "sdcard", "emmc" and "other".

Note that although much of this deals with automated systems (ASU), it will also benefit manual upgrades by providing the user with needed information from a reliable source.

Since there is currently no way to determine which image is installed on-device, we are adding a new mechanism to allow per-target definition of that data and exposing it through the system board call.

On-device generation of "/tmp/sysinfo/image_type" contents is left open so as to allow flexibility of implementation.

Details

To illustrate the selection mechanism, we'll provide an example taken from ath79/generic/profiles.json. This is a minimized snippet, all "images" entries are retained, but unrelated field values have been deleted.

  {
    "profiles": {
      "tplink_archer-c7-v4": {
        "images": [
          {
            "filesystem": "squashfs",
            "name": "openwrt-ath79-generic-tplink_archer-c7-v4-squashfs-sysupgrade.bin",
            "type": "sysupgrade"
          },
          {
            "filesystem": "initramfs",
            "name": "openwrt-ath79-generic-tplink_archer-c7-v4-initramfs-kernel.bin",
            "type": "kernel"
          },
          {
            "filesystem": "squashfs",
            "name": "openwrt-ath79-generic-tplink_archer-c7-v4-squashfs-factory.bin",
            "type": "factory"
          }
        ]
      }
    }
  }

Currently we can derive two of the three keys easily:

  ubus call system board | \
    jsonfilter -e 'profile=$.board_name' \
               -e 'filesystem=$.rootfs_type'

Then image selection becomes

  profiles[$profile].images[@.filesystem = $filesystem && @.type = "sysupgrade"]

For most targets, guessing that the profile's image type is 'sysupgrade' works, but for quite a few it fails.

Examples from x86/64 and spacemit/generic, in both we've omitted many sections and fields to focus on the issue at hand:

  "images": [
    {
      "filesystem": "squashfs",
      "name": "openwrt-x86-64-generic-squashfs-combined.img.gz",
      "type": "combined"
    },
    {
      "filesystem": "squashfs",
      "name": "openwrt-x86-64-generic-squashfs-combined-efi.img.gz",
      "type": "combined-efi"
    }
  ]

  "images": [
    {
      "filesystem": "erofs",
      "name": "openwrt-spacemit-k1-generic-erofs-other.img.gz",
      "type": "other"
    },
    {
      "filesystem": "erofs",
      "name": "openwrt-spacemit-k1-generic-erofs-emmc.img.gz",
      "type": "emmc"
    },
    {
      "filesystem": "erofs",
      "name": "openwrt-spacemit-k1-generic-erofs-sdcard.img.gz",
      "type": "sdcard"
    }
  ]

Link: efahl/owut#68
Link: openwrt/openwrt#23231 (comment)

An ongoing chronic pain point when performing upgrades is determining
which of several images is the correct one.  For most devices,
this is a simple choice between "factory" or "sysupgrade", with the
latter being the correct choice.  On several targets, the choice
is not so obvious.

For example, on the x86/64 target, we have "combined" and
"combined-efi" images, and users must somehow determine which is
appropriate.  The armsr and loongarch devices are simpler with only
"combined-efi", and tegra only has "sdcard".  On the ramips/mt7621
target there are five Mikrotik devices that have both "sysupgrade"
and "sysupgrade-v7".  Further, the new spacemit/k1 target has three:
"sdcard", "emmc" and "other".

Note that although much of this deals with automated systems (ASU),
it will also benefit manual upgrades by providing the user with
needed information from a reliable source.

Since there is currently no way to determine which image is installed
on-device, we are adding a new mechanism to allow per-target
definition of that data and exposing it through the system board call.

On-device generation of "/tmp/sysinfo/image_type" contents is left
open so as to allow flexibility of implementation.

Details
-------
To illustrate the selection mechanism, we'll provide an example
taken from ath79/generic/profiles.json.  This is a minimized snippet,
all "images" entries are retained, but unrelated field values have
been deleted.

  {
    "profiles": {
      "tplink_archer-c7-v4": {
        "images": [
          {
            "filesystem": "squashfs",
            "name": "openwrt-ath79-generic-tplink_archer-c7-v4-squashfs-sysupgrade.bin",
            "type": "sysupgrade"
          },
          {
            "filesystem": "initramfs",
            "name": "openwrt-ath79-generic-tplink_archer-c7-v4-initramfs-kernel.bin",
            "type": "kernel"
          },
          {
            "filesystem": "squashfs",
            "name": "openwrt-ath79-generic-tplink_archer-c7-v4-squashfs-factory.bin",
            "type": "factory"
          }
        ]
      }
    }
  }

Currently we can derive two of the three keys easily:

  ubus call system board | \
    jsonfilter -e 'profile=$.board_name' \
               -e 'filesystem=$.rootfs_type'

Then image selection becomes

  profiles[$profile].images[@.filesystem = $filesystem && @.type = "sysupgrade"]

For most targets, guessing that the profile's image type is
'sysupgrade' works, but for quite a few it fails.

Examples from x86/64 and spacemit/generic, in both we've omitted
many sections and fields to focus on the issue at hand:

  "images": [
    {
      "filesystem": "squashfs",
      "name": "openwrt-x86-64-generic-squashfs-combined.img.gz",
      "type": "combined"
    },
    {
      "filesystem": "squashfs",
      "name": "openwrt-x86-64-generic-squashfs-combined-efi.img.gz",
      "type": "combined-efi"
    }
  ]

  "images": [
    {
      "filesystem": "erofs",
      "name": "openwrt-spacemit-k1-generic-erofs-other.img.gz",
      "type": "other"
    },
    {
      "filesystem": "erofs",
      "name": "openwrt-spacemit-k1-generic-erofs-emmc.img.gz",
      "type": "emmc"
    },
    {
      "filesystem": "erofs",
      "name": "openwrt-spacemit-k1-generic-erofs-sdcard.img.gz",
      "type": "sdcard"
    }
  ]

Link: efahl/owut#68
Link: openwrt/openwrt#23231 (comment)
Signed-off-by: Eric Fahlgren <ericfahlgren@gmail.com>
@efahl

efahl commented Aug 25, 2026

Copy link
Copy Markdown
Author

@aparcar @dangowrt @dhewg

Mostly regarding ASU support. Plan is to get this in, fix up a couple of targets with 03_sysinfo as proposed by @dhewg in openwrt/openwrt#23231 (tldr below) and then fix both owut and LuCI ASU app to handle.

The spacemit/k1 /etc/board.d/03_sysinfo:

#!/bin/sh

. /lib/functions.sh
. /lib/upgrade/common.sh

diskdev=""
image_type=""

export_bootdevice && export_partdevice diskdev 0 || exit 1

sig=$(dd if=/dev/$diskdev bs=1 skip=440 count=4 2>/dev/null | hexdump -v -e '1/1 "%02x"')
case "$sig" in
        53444344) image_type=sdcard ;;
        454d4d43) image_type=emmc ;;
        4f544852) image_type=other ;;
esac
test -n "$image_type" || exit 2

echo "$image_type" > /tmp/sysinfo/image_type
exit 0

@efahl

efahl commented Aug 25, 2026

Copy link
Copy Markdown
Author

Oh, I should also add that I've got this all built and tested end-to-end on two of the spacemit devices.

RV2 (sdcard)

$ owut check -v
owut - OpenWrt Upgrade Tool 2026.07.08~db17536e-r1 (/root/bin/owut)
...
Target         spacemit/k1
Profile        generic
Package-arch   riscv64_generic
Root-FS-type   erofs
Sys-type       sdcard
...
Build-FS-type  erofs
Image-prefix   openwrt-spacemit-k1-generic
Image-URL      https://downloads.openwrt.org/snapshots/targets/spacemit/k1
Image-file     openwrt-spacemit-k1-generic-erofs-sdcard.img.gz

R2S (emmc)

$ owut check -v
...
Target         spacemit/k1
Profile        generic
Package-arch   riscv64_generic
Root-FS-type   erofs
Image-type     emmc
...
Build-FS-type  erofs
Image-prefix   openwrt-spacemit-k1-generic
Image-URL      https://downloads.openwrt.org/snapshots/targets/spacemit/k1
Image-file     openwrt-spacemit-k1-generic-erofs-emmc.img.gz

Comment thread system.c
Comment thread system.c
@dhewg

dhewg commented Aug 26, 2026 via email

Copy link
Copy Markdown
Contributor

@efahl

efahl commented Aug 26, 2026

Copy link
Copy Markdown
Author

Exactly.

Which hopefully results in less special casing in owut.

And also the LuCI Attended Sysupgrade app, which has the same-ish special case code, and same resulting problems.

@map-b

map-b commented Aug 27, 2026

Copy link
Copy Markdown

The Mikrotik v7 images are a multi target pattern, not ramips specific.

(For context)
efahl/owut#68 (comment)

I have checked and there are ~=25 profiles generating these v7 images. The only difference would be a sysupgrade image, your proposal of fake a profile and DTS for each one seems overkill.

As general rule, you are saying that is not possible to create multiple sysupgrade images? Aren't we imposing too much restriction from downstream ASU? IMO Upstream have enough constraints to follow per-se to also suffer some more from an ASU's client context (if it is not strictly necessary).

Reading the PR which implemented this extra v7 sysupgrade images, there is a comment about the idea of only generate one image so this v7 images could be temporal and with your proposal would be harder to undo. This was a creative and effective way to fix this MikroTik bootloader specialness and if it requires some effort from ASU clients to handle these cases, that seems reasonable to me.

Just like this issue original request, can/should we have a new parameter for sutype (Sys-Type) in owut CLI as fallback anyway?

The special code required in owut to handle these v7 extra images can be generic enough and minimal for the ~=25 actual devices and will be fine with any upcoming new devices support.

PoC:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants